﻿using System;
using GeckoBrowser.Data;
using GeckoBrowser.Enums;
using GeckoBrowser.GUIConfiguration;
using GeckoBrowser.Utils;
using GeckoBrowser.WebBrowser;
using MediaPortal.Configuration;
using MediaPortal.GUI.Library;
using MediaPortal.Profile;
using Skybound.Gecko;

namespace GeckoBrowser.GUIWindows
{
    public sealed class GUIWebBrowser : GUIWindow, ISetupForm
    {
        [SkinControlAttribute(2)] private GUIButtonControl btnBack = null;
        [SkinControlAttribute(3)] private GUIButtonControl btnForward = null;
        [SkinControlAttribute(4)] private GUIButtonControl btnRefresh = null;
        [SkinControlAttribute(5)] private GUIButtonControl btnStop = null;
        [SkinControlAttribute(6)] private GUIButtonControl btnHome = null;
        [SkinControlAttribute(7)] private GUIButtonControl btnFav = null;
        [SkinControlAttribute(8)] private GUIButtonControl btnUrl = null;

        #region Variables
        public const int WindowWebBrowser = 16002;
        private static readonly Logger logger = Logger.GetInstance();
        private bool _initSuccess;
        #endregion

        #region Delegates
        private delegate void InitializeControlsDelegate();
        #endregion

        #region Fields
        public string LinkId { get; set; }
        #endregion

        #region ISetupForm Members

        // Returns the name of the plugin which is shown in the plugin menu
        public string PluginName()
        {
            return "GeckoBrowser";
        }

        // Returns the description of the plugin is shown in the plugin menu
        public string Description()
        {
            return "A WebBrowser plugin";
        }

        // Returns the author of the plugin which is shown in the plugin menu
        public string Author()
        {
            return "edsche";
        }

        // show the setup dialog
        public void ShowPlugin()
        {
            ConfigForm config = new ConfigForm();
            config.ShowDialog();
        }

        // Indicates whether plugin can be enabled/disabled
        public bool CanEnable()
        {
            return true;
        }

        // Indicates if plugin is enabled by default;
        public bool DefaultEnabled()
        {
            return true;
        }

        // indicates if a plugin has it's own setup screen
        public bool HasSetup()
        {
            return true;
        }
        public int GetWindowId()
        {
            return WindowWebBrowser;
        }

        /// <summary>
        /// If the plugin should have it's own button on the main menu of Mediaportal then it
        /// should return true to this method, otherwise if it should not be on home
        /// it should return false
        /// </summary>
        /// <param name="strButtonText">text the button should have</param>
        /// <param name="strButtonImage">image for the button, or empty for default</param>
        /// <param name="strButtonImageFocus">image for the button, or empty for default</param>
        /// <param name="strPictureImage">subpicture for the button or empty for none</param>
        /// <returns>true : plugin needs it's own button on home
        /// false : plugin does not need it's own button on home</returns>

        public bool GetHome(out string strButtonText, out string strButtonImage,
          out string strButtonImageFocus, out string strPictureImage)
        {
            strButtonText = PluginName();
            strButtonImage = String.Empty;
            strButtonImageFocus = String.Empty;
            strPictureImage = String.Empty;
            return true;
        }

        #endregion

        #region Constructor

        /// <summary>
        /// Initializes a new instance of the <see cref="GUIWebBrowser"/> class.
        /// </summary>
        public GUIWebBrowser()
        {
            GetID = WindowWebBrowser;
        }

        #endregion

        
        #region Overrides
        protected override void OnClicked(int controlId, GUIControl control, Action.ActionType actionType)
        {
            if (control == btnBack)
            {
                WebBrowserManager.GoBack();
                logger.WriteLog("Triggered the \"Go Back\" button", LogLevel.Debug);
            }
            else if (control == btnForward)
            {
                WebBrowserManager.GoForward();
                logger.WriteLog("Triggered the \"Go Forward\" button", LogLevel.Debug);
            }
            else if (control == btnRefresh)
            {
                WebBrowserManager.RefreshBrowser();
                logger.WriteLog("Triggered the \"Refresh\" button", LogLevel.Debug);
            }
            else if (control == btnStop)
            {
                WebBrowserManager.StopBrowser();
                logger.WriteLog("Triggered the \"Stop\" button", LogLevel.Debug);
            }
            else if (control == btnHome)
            {
                WebBrowserManager.GoHome();
                logger.WriteLog("Triggered the \"Home\" button", LogLevel.Debug);
            }
            else if (control == btnUrl)
            {
                InitializeControlsDelegate d = new InitializeControlsDelegate(ShowUrlDialog);
                GUIGraphicsContext.form.BeginInvoke(d);
                
            }

            base.OnClicked(controlId, control, actionType);
        }

        public void ShowUrlDialog()
        {
            logger.WriteLog("Triggered the \"Enter Url\" button", LogLevel.Debug);
            string link = String.Empty;
            WebBrowserManager.HideWebBrowser();


            bool confirmed = GeckoBrowserUtils.ShowKeyboard(ref link, true);
            if (confirmed)
            {
                GeckoBrowserUtils.SetProperty("#geckobrowser.link", String.Empty);
                GeckoBrowserUtils.SetProperty("#geckobrowser.linkzoom", String.Empty);
                GeckoBrowserUtils.SetProperty("#geckobrowser.link.shorturl", String.Empty);
                WebBrowserManager.Navigate(link, WebBrowserManager.GetDefaultZoom());
            }
            WebBrowserManager.ShowWebBrowser();
        }

        public void ShowInputDialog(HtmlLinkNumber id)
        {
            logger.WriteLog("Entered a INPUT field of website", LogLevel.Debug);
            string text = String.Empty;
            WebBrowserManager.HideWebBrowser();


            bool confirmed = GeckoBrowserUtils.ShowKeyboard(ref text, true);
            if (confirmed)
            {
                WebBrowserManager.SetInputFieldText(id.Number, text);
            }
            WebBrowserManager.ShowWebBrowser();
        }

        /// <summary>
        /// Inits this instance.
        /// </summary>
        /// <returns></returns>
        public override bool Init()
        {
            GeckoBrowserUtils.InitLog();
            if (WebBrowserManager.InitWebBrowser())
            {
                using (Settings settings = new Settings(Config.GetFile(Config.Dir.Config, "MediaPortal.xml")))
                {
                    WebBrowserManager.Startpage = settings.GetValueAsString("GeckoBrowser", "Startpage", "");
                    WebBrowserManager.ZoomStep = settings.GetValueAsInt("GeckoBrowser", "Zoomstep", 10);
                    WebBrowserManager.DefaultZoom = settings.GetValueAsInt("GeckoBrowser", "Defaultzoom", 100);
                    WebBrowserManager.MouselessBrowsing = settings.GetValueAsBool("GeckoBrowser", "RemoteBrowsing", false);
                }
                _initSuccess = true;
            }
            else _initSuccess = false;
            bool success = Load(GUIGraphicsContext.Skin + @"\geckobrowser.xml");
            return success;
        }

        /// <summary>
        /// Called when [action].
        /// </summary>
        /// <param name="action">The action.</param>
        public override void OnAction(Action action)
        {
            if (_initSuccess)
            {
                switch (action.wID)
                {
                    case Action.ActionType.REMOTE_1:
                        {
                            if (WebBrowserManager.MouselessBrowsing)
                            {
                                LinkId += 1;
                                GeckoBrowserUtils.SetProperty("#geckobrowser.linkid", "Navigate to LinkID: " + LinkId);
                            }
                            break;
                        }
                    case Action.ActionType.REMOTE_2:
                        {
                            if (WebBrowserManager.MouselessBrowsing)
                            {
                                LinkId += 2;
                                GeckoBrowserUtils.SetProperty("#geckobrowser.linkid", "Navigate to LinkID: " + LinkId);
                            }
                            break;
                        }
                    case Action.ActionType.REMOTE_3:
                        {
                            if (WebBrowserManager.MouselessBrowsing)
                            {
                                LinkId += 3;
                                GeckoBrowserUtils.SetProperty("#geckobrowser.linkid", "Navigate to LinkID: " + LinkId);
                            }
                            break;
                        }
                    case Action.ActionType.REMOTE_4:
                        {
                            if (WebBrowserManager.MouselessBrowsing)
                            {
                                LinkId += 4;
                                GeckoBrowserUtils.SetProperty("#geckobrowser.linkid", "Navigate to LinkID: " + LinkId);
                            }
                            break;
                        }
                    case Action.ActionType.REMOTE_5:
                        {
                            if (WebBrowserManager.MouselessBrowsing)
                            {
                                LinkId += 5;
                                GeckoBrowserUtils.SetProperty("#geckobrowser.linkid", "Navigate to LinkID: " + LinkId);
                            }
                            break;
                        }
                    case Action.ActionType.REMOTE_6:
                        {
                            if (WebBrowserManager.MouselessBrowsing)
                            {
                                LinkId += 6;
                                GeckoBrowserUtils.SetProperty("#geckobrowser.linkid", "Navigate to LinkID: " + LinkId);
                            }
                            break;
                        }
                    case Action.ActionType.REMOTE_7:
                        {
                            if (WebBrowserManager.MouselessBrowsing)
                            {
                                LinkId += 7;
                                GeckoBrowserUtils.SetProperty("#geckobrowser.linkid", "Navigate to LinkID: " + LinkId);
                            }
                            break;
                        }
                    case Action.ActionType.REMOTE_8:
                        {
                            if (WebBrowserManager.MouselessBrowsing)
                            {
                                LinkId += 8;
                                GeckoBrowserUtils.SetProperty("#geckobrowser.linkid", "Navigate to LinkID: " + LinkId);
                            }
                            break;
                        }
                    case Action.ActionType.REMOTE_9:
                        {
                            if (WebBrowserManager.MouselessBrowsing)
                            {
                                LinkId += 9;
                                GeckoBrowserUtils.SetProperty("#geckobrowser.linkid", "Navigate to LinkID: " + LinkId);
                            }
                            break;
                        }
                    case Action.ActionType.REMOTE_0:
                        {
                            if (WebBrowserManager.MouselessBrowsing)
                            {
                                LinkId += 0;
                                GeckoBrowserUtils.SetProperty("#geckobrowser.linkid", "Navigate to LinkID: " + LinkId);
                            }
                            break;
                        }
                    case Action.ActionType.ACTION_CONTEXT_MENU:
                        {
                            if (WebBrowserManager.MouselessBrowsing)
                            {
                                HtmlLinkNumber hln = null;
                                if (WebBrowserManager.GetLinkById(Convert.ToInt32(LinkId), out hln))
                                {
                                    switch (hln.Type)
                                    {
                                        case HtmlInputType.Link:
                                            WebBrowserManager.Navigate(hln.Link, WebBrowserManager.GetDefaultZoom());
                                            break;
                                        case HtmlInputType.Input:
                                            ShowInputDialog(hln);
                                            break;
                                        case HtmlInputType.Action:
                                            WebBrowserManager.Navigate("javascript:document.getElementById(\"" + hln.Id + "\").click()");
                                            break;
                                    }
                                }
                                LinkId = string.Empty;
                                GeckoBrowserUtils.SetProperty("#geckobrowser.linkid", "Navigate to LinkID: -");
                            }
                            break;
                        }
                    case Action.ActionType.ACTION_PAGE_DOWN:
                        {
                            WebBrowserManager.ZoomOut(WebBrowserManager.ZoomStep);
                            break;
                        }
                    case Action.ActionType.ACTION_PAGE_UP:
                        {
                            WebBrowserManager.ZoomIn(WebBrowserManager.ZoomStep);
                            break;
                        }
                    case Action.ActionType.ACTION_PREVIOUS_MENU:
                        {
                            GUIWindowManager.ShowPreviousWindow();
                            return;
                        }
                    case Action.ActionType.ACTION_MOVE_DOWN:
                        {
                            WebBrowserManager.ScrollDown(100);
                            break;
                        }
                    case Action.ActionType.ACTION_MOVE_UP:
                        {
                            WebBrowserManager.ScrollUp(100);
                            break;
                        }
                    case Action.ActionType.ACTION_MOVE_LEFT:
                        {
                            WebBrowserManager.ScrollLeft(100);
                            break;
                        }
                    case Action.ActionType.ACTION_MOVE_RIGHT:
                        {
                            WebBrowserManager.ScrollRight(100);
                            break;
                        }
                    case Action.ActionType.ACTION_MOUSE_MOVE:
                        {
                            WebBrowserManager.Focus();
                            /*if (!GUIGraphicsContext.form.Controls[wbCtrlNr].Enabled)
                            {
                             
                                //wbc.FocusWebBrowser();
                                //Cursor.Show();
                            }*/
                            break;
                        }
                }
            }
            base.OnAction(action);
        }

        protected override void OnPageLoad()
        {
            if (_initSuccess)
            {
                WebBrowserManager.SetWebBrowserWindow();
                while(WebBrowserManager.InitializationInProgress)
                {
                    System.Windows.Forms.Application.DoEvents();
                }
                WebBrowserManager.Navigate(WebBrowserManager.GetStartpageLink(), WebBrowserManager.GetDefaultZoom());
            }
            else
            {
                GeckoBrowserUtils.ShowDialogOkWindow("Error!", "Initializing GeckoBrowser was unsuccessful. See log for details.");
                GUIWindowManager.ShowPreviousWindow();
            }
            base.OnPageLoad();
        }
        protected override void OnPageDestroy(int newWindowId)
        {
            if (_initSuccess)
            {
                WebBrowserManager.UnsetWebBrowserWindow();
            }
            base.OnPageDestroy(newWindowId);
        }
        #endregion    
    }
}
